import unittest
import pytz
import email.utils
from datetime import datetime
from mailbox import mboxMessage

from src.archive import Archive
from src.tree import Tree

class ArchiveTest(unittest.TestCase):
     
    def setUp(self):
        filename = "tests/archivetotest"
        self.archive = Archive(filename)

    def test_make_tree_without_replys(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "root email for test"
        email2.set_payload("hi everybody, this is only a test")
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3.set_payload("hi everybody, this is only a test")
                       
        tree = Tree()
        dummy_root = tree.add(None)
        
        email1_node = tree.add(email1, dummy_root)
        email2_node = tree.add(email2, dummy_root)
        email3_node = tree.add(email3, dummy_root)
        
        expected_tree = self.archive.make_tree([email1, email2, email3])
        root_children = expected_tree.root.children
        
        self.assertEquals(root_children[0].elem, email1_node.elem)
        self.assertEquals(root_children[1].elem, email2_node.elem)
        self.assertEquals(root_children[2].elem, email3_node.elem)
        
        self.assertEquals(root_children[0].children, [])
        self.assertEquals(root_children[0].children, [])
        self.assertEquals(root_children[0].children, [])
        
    def test_make_tree_chain_replys(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "root email for test"
        email2["references"] = "1"
        email2.set_payload("hi everybody, this is only a test")
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "2"
        email3.set_payload("hi everybody, this is only a test")
                       
        tree = Tree()
        dummy_root = tree.add(None)
        
        email1_node = tree.add(email1, dummy_root)
        email2_node = tree.add(email2, email1_node)
        email3_node = tree.add(email3, email2_node)
        
        expected_tree = self.archive.make_tree([email1, email2, email3])
        root_children = expected_tree.root.children
        
        self.assertEquals(root_children[0].elem, email1_node.elem)
        self.assertEquals([e.elem for e in root_children[0].children],
                          [email2_node.elem])
        
        self.assertEquals([e.elem for e in root_children[0].children[0].children],
                          [email3_node.elem])
    
    
    def test_make_tree_multi_value_references(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "root email for test"
        email2["references"] = "1"
        email2.set_payload("hi everybody, this is only a test")
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "1\n\t2"
        email3.set_payload("hi everybody, this is only a test")
                       
        tree = Tree()
        dummy_root = tree.add(None)
        
        email1_node = tree.add(email1, dummy_root)
        email2_node = tree.add(email2, email1_node)
        email3_node = tree.add(email3, email2_node)
        
        expected_tree = self.archive.make_tree([email1, email2, email3])
        root_children = expected_tree.root.children
        
        self.assertEquals(root_children[0].elem, email1_node.elem)
        self.assertEquals([e.elem for e in root_children[0].children],
                          [email2_node.elem])
        
        self.assertEquals([e.elem for e in root_children[0].children[0].children],
                          [email3_node.elem])
                          
    
    def test_make_tree_mix_inreplyto_and_references(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "root email for test"
        email2["in-reply-to"] = "1"
        email2.set_payload("hi everybody, this is only a test")
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "2"
        email3.set_payload("hi everybody, this is only a test")
                       
        tree = Tree()
        dummy_root = tree.add(None)
        
        email1_node = tree.add(email1, dummy_root)
        email2_node = tree.add(email2, email1_node)
        email3_node = tree.add(email3, email2_node)
        
        expected_tree = self.archive.make_tree([email1, email2, email3])
        root_children = expected_tree.root.children
        
        self.assertEquals(root_children[0].elem, email1_node.elem)
        self.assertEquals([e.elem for e in root_children[0].children],
                          [email2_node.elem])
        
        self.assertEquals([e.elem for e in root_children[0].children[0].children],
                          [email3_node.elem])
    
    def test_make_tree_replys_no_order(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "root email for test"
        email2["references"] = "1"
        email2.set_payload("hi everybody, this is only a test")
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "2"
        email3.set_payload("hi everybody, this is only a test")
                       
        tree = Tree()
        dummy_root = tree.add(None)
        
        email1_node = tree.add(email1, dummy_root)
        email2_node = tree.add(email2, email1_node)
        email3_node = tree.add(email3, email2_node)
        
        expected_tree = self.archive.make_tree([email1, email3, email2])
        root_children = expected_tree.root.children
        
        self.assertEquals(root_children[0].elem, email1_node.elem)
        self.assertEquals([e.elem for e in root_children[0].children],
                          [email2_node.elem])
        
        self.assertEquals([e.elem for e in root_children[0].children[0].children],
                          [email3_node.elem])


    def test_make_tree_replys_by_subject(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "Re: root email for test"
        email2.set_payload("hi everybody, this is only a test")
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "2"
        email3.set_payload("hi everybody, this is only a test")
                       
        tree = Tree()
        dummy_root = tree.add(None)
        
        email1_node = tree.add(email1, dummy_root)
        email2_node = tree.add(email2, email1_node)
        email3_node = tree.add(email3, email2_node)
        
        expected_tree = self.archive.make_tree([email1, email2, email3])
        root_children = expected_tree.root.children
        
        self.assertEquals(root_children[0].elem, email1_node.elem)
        self.assertEquals([e.elem for e in root_children[0].children],
                          [email2_node.elem])
        
        self.assertEquals([e.elem for e in root_children[0].children[0].children],
                          [email3_node.elem])
                          
    def test_make_tree_replys_by_subject_with_listname(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jose@presley.com"))
        email1["subject"] = "root email for test"
        email1.set_payload("hi everybody, this is only a test")
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "maria@presley.com"))
        email2["subject"] = "Re: [list name] root email for test"
        email2.set_payload("hi everybody, this is only a test")
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "joao@presley.com"))
        email3["subject"] = "root email for test"
        email3["references"] = "2"
        email3.set_payload("hi everybody, this is only a test")
                       
        tree = Tree()
        dummy_root = tree.add(None)
        
        email1_node = tree.add(email1, dummy_root)
        email2_node = tree.add(email2, email1_node)
        email3_node = tree.add(email3, email2_node)
        
        expected_tree = self.archive.make_tree([email1, email2, email3])
        root_children = expected_tree.root.children
        
        self.assertEquals(root_children[0].elem, email1_node.elem)
        self.assertEquals([e.elem for e in root_children[0].children],
                          [email2_node.elem])
        
        self.assertEquals([e.elem for e in root_children[0].children[0].children],
                          [email3_node.elem])
                          
    def test_make_tree_replys_by_jira_subject(self):
        email1 = mboxMessage()
        email1["message-id"] = "1"
        email1["from"] = email.utils.formataddr(("Jose", "jira@apache.org"))
        email1["subject"] = "[jira] Created: (LUCENE-1582) test subject"
        email1.set_payload("hi everybody, this is only a test")
        
        email2 = mboxMessage()
        email2["message-id"] = "2"
        email2["from"] = email.utils.formataddr(("Maria", "jira@apache.org"))
        email2["subject"] = "[jira] Commented: (LUCENE-1582) test subject"
        email2.set_payload("hi everybody, this is only a test")
                       
        email3 = mboxMessage()
        email3["message-id"] = "3"
        email3["from"] = email.utils.formataddr(("Joao", "jira@apache.org"))
        email3["subject"] = "[jira] Updated: (LUCENE-1582) test subject"
        email3.set_payload("hi everybody, this is only a test")
                       
        tree = Tree()
        dummy_root = tree.add(None)
        
        email1_node = tree.add(email1, dummy_root)
        email2_node = tree.add(email2, email1_node)
        email3_node = tree.add(email3, email1_node)
        
        expected_tree = self.archive.make_tree([email1, email2, email3])
        root_children = expected_tree.root.children
        
        self.assertEquals(root_children[0].elem, email1_node.elem)
        self.assertEquals([e.elem for e in root_children[0].children],
                          [email2_node.elem, email3_node.elem])
